﻿///<reference path="BasketModel.ts"/>
///<reference path="CustomerModel.ts"/>
///<reference path="DeliveryMethodModel.ts"/>
///<reference path="PaymentMethodModel.ts"/>

module Enferno.Public.Web.Components.Models {
    
    export class CheckoutModelBase<TCheckoutPayer extends ICheckoutPayerModel, TCheckoutShipTo extends ICheckoutShipToModel> {

        public buyer: CheckoutBuyerModel;
        public payer: TCheckoutPayer;
        public shipTo: TCheckoutShipTo;
        public deliveryMethods: Array<DeliveryMethodModel>;
        public paymentMethods: Array<PaymentMethodModel>;
        public orderReference: string;

        constructor();
        constructor(serverObject: any);
        constructor(serverObject?: any) {
            if (serverObject != null) {
                this.createFromServerObject(serverObject);
            }
        }

        private createFromServerObject(serverObject: any) {
            this.buyer = serverObject.buyer != null ? new CheckoutBuyerModel(serverObject.buyer) : null;
            this.deliveryMethods = serverObject.deliveryMethods != null ? Enumerable.from(serverObject.deliveryMethods).select(deliveryMethod => new DeliveryMethodModel(deliveryMethod)).toArray() : [];
            this.paymentMethods = serverObject.paymentMethods != null ? Enumerable.from(serverObject.paymentMethods).select(paymentMethod => new PaymentMethodModel(paymentMethod)).toArray() : [];
            this.orderReference = serverObject.orderReference;
        }

        public serialize(): any {
            var obj: any = {};
            obj.buyer = this.buyer != null ? this.buyer.serialize() : null;
            obj.payer = this.payer != null ? this.payer.serialize() : null;
            obj.shipTo = this.shipTo != null ? this.shipTo.serialize() : null;

            if (this.deliveryMethods != null) {
                obj.deliveryMethods = Enumerable.from(this.deliveryMethods).select((deliveryMethod: DeliveryMethodModel) => deliveryMethod.serialize()).toArray();
            } else {
                obj.deliveryMethods = [];
            }

            if (this.paymentMethods != null) {
                obj.paymentMethods = Enumerable.from(this.paymentMethods).select((paymentMethod: DeliveryMethodModel) => paymentMethod.serialize()).toArray();
            } else {
                obj.paymentMethods = [];
            }

            obj.orderReference = this.orderReference;

            return obj;
        }

    }

    export class PrivateCheckoutModel extends CheckoutModelBase<CheckoutPrivatePayerModel, CheckoutPrivateShipToModel> {

        constructor();
        constructor(serverObject: any);
        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.payer = serverObject.payer != null ? new CheckoutPrivatePayerModel(serverObject.payer) : null;
                this.shipTo = serverObject.shipTo != null ? new CheckoutPrivateShipToModel(serverObject.shipTo) : null;
            }
        }
    }

    export class CompanyCheckoutModel extends CheckoutModelBase<CheckoutCompanyPayerModel, CheckoutCompanyShipToModel> {

        constructor();
        constructor(serverObject: any);
        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.payer = serverObject.payer != null ? new CheckoutCompanyPayerModel(serverObject.payer) : null;
                this.shipTo = serverObject.shipTo != null ? new CheckoutCompanyShipToModel(serverObject.shipTo) : null;
            }
        }
    }

    export class CheckoutBuyerModel extends PersonInformationModel {

        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.customerId = serverObject.customerId;
            }
        }

        public serialize(): any {
            var obj = super.serialize();
            obj.customerId = this.customerId;

            return obj;
        }

        customerId: number;
    }

    export interface ICheckoutPayerModel
    {
        customerId: number;
        invoiceAddress: AddressModel;
        serialize(): any;
    }

    export class CheckoutPayerModel implements ICheckoutPayerModel
    {
        constructor(serverObject?: any) {
            if (serverObject != null) {
                this.customerId = serverObject.customerId;
                this.invoiceAddress = new AddressModel(serverObject.invoiceAddress);
            }
        }

        public serialize(): any {
            var obj: any = {};
            obj.customerId = this.customerId;
            obj.invoiceAddress = this.invoiceAddress != null ? this.invoiceAddress.serialize() : null;

            return obj;
        }

        public customerId: number;
        public invoiceAddress: AddressModel;
}

    export class CheckoutCompanyPayerModel extends CheckoutPayerModel
    {
        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.companyId = serverObject.companyId;
                this.companyCode = serverObject.companyCode;
                this.organisationNumber = serverObject.organisationNumber;
                this.companyInformation = serverObject.companyInformation != null ? new CompanyInformationModel(serverObject.companyInformation) : null;
                if (this.companyInformation.name === '0') // \0
                    this.companyInformation.name = undefined;
            }
        }

        public serialize(): any {
            var obj = super.serialize();
            obj.companyId = this.companyId;
            obj.companyCode = this.companyCode;
            obj.organisationNumber = this.organisationNumber;
            obj.companyInformation = this.companyInformation != null ? this.companyInformation.serialize() : null;
            if ((typeof obj.companyInformation.name) === 'undefined')
                obj.companyInformation.name = '0'; // \0
            return obj;
        }

        public companyId: number;
        public companyCode: string;
        public organisationNumber: string;
        public companyInformation: CompanyInformationModel;
    }

    export class CheckoutPrivatePayerModel extends  CheckoutPayerModel
    {
        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.socialSecurityNumber = serverObject.socialSecurityNumber;
                this.personInformation = serverObject.personInformation != null ? new PersonInformationModel(serverObject.personInformation) : null;
            }
        }

        public serialize(): any {
            var obj = super.serialize();
            obj.socialSecurityNumber = this.socialSecurityNumber;
            obj.personInformation = this.personInformation != null ? this.personInformation.serialize() : null;

            return obj;
        }

        public socialSecurityNumber: string;
        public personInformation: PersonInformationModel;
    }

    export interface ICheckoutShipToModel {
        customerId: number;
        deliveryAddress: AddressModel;
        serialize(): any;
    }

    export class CheckoutShipToModel implements ICheckoutShipToModel {

        constructor(serverObject?: any) {
            if (serverObject != null) {
                this.customerId = serverObject.customerId;
                this.deliveryAddress = new AddressModel(serverObject.deliveryAddress);
            }
        }

        public serialize(): any {
            var obj: any = {};
            obj.customerId = this.customerId;
            obj.deliveryAddress = this.deliveryAddress != null ? this.deliveryAddress.serialize() : null;

            return obj;
        }

        public customerId: number;
        public deliveryAddress: AddressModel;
    }

    export class CheckoutCompanyShipToModel extends CheckoutShipToModel {
        public companyId: number;
        public companyCode: string;
        public organisationNumber: string;
        public companyInformation: CompanyInformationModel;

        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.companyId = serverObject.companyId;
                this.companyCode = serverObject.companyCode;
                this.organisationNumber = serverObject.organisationNumber;
                this.companyInformation = serverObject.companyInformation != null ? new CompanyInformationModel(serverObject.companyInformation) : null;
                if (this.companyInformation.name === '0') // \0
                    this.companyInformation.name = undefined;
            }
        }

        public serialize(): any {
            var obj = super.serialize();
            obj.companyId = this.companyId;
            obj.companyCode = this.companyCode;
            obj.organisationNumber = this.organisationNumber;
            obj.companyInformation = this.companyInformation != null ? this.companyInformation.serialize() : null;
            if ((typeof obj.companyInformation.name) === 'undefined')
                obj.companyInformation.name = '0'; // \0
            return obj;
        }
    }

    export class CheckoutPrivateShipToModel extends CheckoutShipToModel {
        public socialSecurityNumber: string;
        public personInformation: PersonInformationModel;

        constructor(serverObject?: any) {
            super(serverObject);
            if (serverObject != null) {
                this.socialSecurityNumber = serverObject.socialSecurityNumber;
                this.personInformation = serverObject.personInformation != null ? new PersonInformationModel(serverObject.personInformation) : null;
            }
        }

        public serialize(): any {
            var obj = super.serialize();
            obj.socialSecurityNumber = this.socialSecurityNumber;
            obj.personInformation = this.personInformation != null ? this.personInformation.serialize() : null;

            return obj;
        }
    }
} 